home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / QuickDraw / CollectPictColors / CLUTBuilder.c next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  8.7 KB  |  343 lines  |  [TEXT/KAHL]

  1. /*------------------------------------------------------------------------------
  2. #
  3. #    Apple Macintosh Developer Technical Support
  4. #
  5. #    KnowsPICT  by Jon Zap
  6. #
  7. #    CLUTBuilder.c    -    C Source
  8. #
  9. #    Copyright © 1989 Apple Computer, Inc.
  10. #    All rights reserved.
  11. #
  12. #
  13. # this file contains functions used to pull colors from a PICT.  You activate it by
  14. # calling CollectColors(PicHandle) with PicHandle set to a PICT that you have already
  15. # loaded into memory.  It will almost invariably return a (handle to a) color table
  16. # (that contains at least black and white) however the color table is not at all clean
  17. # in the current implementation.  It is probably ok if you run it through NewPalette.
  18. # If it runs across a direct pixmap it won't bomb but it won't add any colors to the
  19. # color table.
  20. #
  21. # WARNING: This code has been tested but it has not been tested thoroughly;
  22. # USE AT YOUR OWN RISK!
  23. ------------------------------------------------------------------------------*/
  24.  
  25. #define    applec
  26.  
  27. OSErr    gColorError;    /* to report errors from bottlenecks. */
  28. CTabHandle gColorTable;    /* to collect colors from bottlenecks. */
  29. short gNextCSpec;        /* next CSpec entry in color table */
  30. short foundDirect;        /* set to true if we uncover a direct pixmap */
  31. short maxPixDepth;      /* depth of deepest pixmap found */
  32.  
  33. /* Add a color to the color table. */
  34. void AddRGBColor(rgb)
  35. RGBColor *rgb;
  36. {
  37.     long numSpecs,sizeInBytes;
  38.     int     i,ctSize;
  39.     CTabPtr TablePtr;
  40.     RGBColor rgbx;
  41.     
  42.     if (gColorError)
  43.         return;
  44.     
  45.     TablePtr = (*gColorTable);
  46.     ctSize = TablePtr -> ctSize;
  47.     for (i = 0; i <= ctSize; i++) {
  48.         rgbx = TablePtr->ctTable[i].rgb;
  49.         if (rgbx.red==(*rgb).red &&
  50.             rgbx.green==(*rgb).green &&
  51.             rgbx.blue==(*rgb).blue) 
  52.             return;        /* if already there, done */
  53.     }
  54.     numSpecs = (long) (++(**gColorTable).ctSize);    /* add a colorspec to table */
  55.     sizeInBytes = (numSpecs * sizeof(ColorSpec)) + sizeof(ColorTable);
  56.     SetHandleSize((Handle)gColorTable, sizeInBytes);
  57.     if ((gColorError = MemError()) == noErr) {
  58.         (**gColorTable).ctTable[numSpecs].rgb = *rgb;
  59.         (**gColorTable).ctTable[numSpecs].value = 0;
  60.     }
  61. }
  62.  
  63. /* Add the contents of another color table to our color table.*/
  64. void AddColorTable(cTab)
  65. CTabHandle cTab;
  66. {
  67.     short index,size;
  68.     RGBColor color;
  69.     size = (**cTab).ctSize;
  70.     for (index= 0; index <= size; index++) {
  71.         color = (**cTab).ctTable[index].rgb;
  72.         AddRGBColor(&color);
  73.     }
  74. }
  75.  
  76. /* Add the foreground color of the current port to the color table. */
  77. void AddRGBForeColor()
  78. {
  79. #ifdef applec
  80.     AddRGBColor(&((*(CGrafPtr)qd.thePort).rgbFgColor));
  81. #else
  82.     AddRGBColor(&((*(CGrafPtr)thePort).rgbFgColor));
  83. #endif
  84. }
  85.  
  86. /* Add the background color of the current port to the color table. */
  87. void AddRGBBackColor()
  88. {
  89. #ifdef applec
  90.     AddRGBColor(&((*(CGrafPtr)qd.thePort).rgbBkColor));
  91. #else
  92.     AddRGBColor(&((*(CGrafPtr)thePort).rgbBkColor));
  93. #endif
  94. }
  95.  
  96. /* Add colors from a PixPat to a color table. */
  97. void AddPixPat(pPat)
  98. PixPatHandle pPat;
  99. {
  100.     switch ((**pPat).patType) {
  101.     
  102.     case 0:        /* one-bit patterns are drawn in the foreground and background color. */
  103.         AddRGBForeColor();
  104.         AddRGBBackColor();
  105.         break;
  106.     case 1:        /* Type 1 PixPats have a color table. */
  107.         AddColorTable((**(**pPat).patMap).pmTable);
  108.         break;
  109.     }
  110. }
  111.  
  112. /* Add colors from the pen PixPat to the color table. */
  113. void AddPenPixPat()
  114. {
  115. #ifdef applec
  116.     AddPixPat((*(CGrafPtr)qd.thePort).pnPixPat);
  117. #else
  118.     AddPixPat((*(CGrafPtr)thePort).pnPixPat);
  119. #endif
  120. }
  121.  
  122. /* Add colors from the fill PixPat to the color table. */
  123. void AddFillPixPat()
  124. {
  125. #ifdef applec
  126.     AddPixPat((*(CGrafPtr)qd.thePort).fillPixPat);
  127. #else
  128.     AddPixPat((*(CGrafPtr)thePort).fillPixPat);
  129. #endif
  130. }
  131.  
  132. /* Add colors because we are about to draw an object. */
  133. void AddVerb(verb)
  134. GrafVerb verb;
  135. {
  136.     switch (verb) {
  137.     
  138.     case frame:
  139.     case paint: /* Framed and painted objects are drawn in the pen PixPat. */
  140.             AddPenPixPat();
  141.             break;
  142.     case erase: /* Erased objects are drawn in the background color. */
  143.             AddRGBBackColor();
  144.             break;
  145.     case fill:
  146.             /* Filled objects are drawn in the fill PixPat.  The fillPixPat is
  147.                 a pattern used to record fill commands for pictures.  First, a
  148.                 command to set the fillPixPat is recorded, then the fill command
  149.                 is recorded. */
  150.             AddFillPixPat();
  151.     }
  152. }
  153.  
  154. /* bottleneck routines follow . . . */
  155.  
  156. pascal void ColorTextProc(byteCount, textBuf, numer, denom)
  157. short byteCount;
  158. Ptr textBuf;
  159. Point numer,denom;
  160. {    /* Text is drawn with the foreground and background colors.*/
  161. #ifdef applec
  162. #pragma unused (byteCount, textBuf, numer, denom)
  163. #endif
  164.     AddRGBForeColor();
  165.     AddRGBBackColor();
  166. }
  167.  
  168. pascal void ColorLineProc(newPt)
  169. Point newPt;
  170. { /* Lines are drawn with the pen PixPat. */
  171. #ifdef applec
  172. #pragma unused (newPt)
  173. #endif
  174.     AddPenPixPat();
  175. }
  176.  
  177. pascal void ColorRectProc(verb, r)
  178. GrafVerb verb;
  179. Rect *r;
  180. {
  181. #ifdef applec
  182. #pragma unused (r)
  183. #endif
  184.     AddVerb(verb);
  185. }
  186.  
  187. pascal void ColorRRectProc(verb, r, ovalWidth, ovalHeight)
  188. GrafVerb verb;
  189. Rect *r;
  190. short ovalWidth;
  191. short ovalHeight;
  192. {
  193. #ifdef applec
  194. #pragma unused (r, ovalWidth, ovalHeight)
  195. #endif
  196.     AddVerb(verb);
  197. }
  198.  
  199. pascal void ColorOvalProc(verb, r)
  200. GrafVerb verb;
  201. Rect *r;
  202. {
  203. #ifdef applec
  204. #pragma unused (r)
  205. #endif
  206.     AddVerb(verb);
  207. }
  208.  
  209. pascal void ColorArcProc(verb, r, startAngle, arcAngle)
  210. GrafVerb verb;
  211. Rect *r;
  212. short startAngle, arcAngle;
  213. {
  214. #ifdef applec
  215. #pragma unused (r, startAngle, arcAngle)
  216. #endif
  217.     AddVerb(verb);
  218. }
  219.  
  220. pascal void ColorPolyProc(verb, poly)
  221. GrafVerb verb;
  222. PolyHandle poly;
  223. {
  224. #ifdef applec
  225. #pragma unused (poly)
  226. #endif
  227.     AddVerb(verb);
  228. }
  229.  
  230. pascal void ColorRgnProc(verb, rgn)
  231. GrafVerb verb;
  232. RgnHandle rgn;
  233. {
  234. #ifdef applec
  235. #pragma unused (rgn)
  236. #endif
  237.     AddVerb(verb);
  238. }
  239.  
  240. pascal void ColorBitsProc(bitPtr, srcRect, dstRect, mode, maskRgn)
  241. BitMap *bitPtr;
  242. Rect *srcRect, *dstRect;
  243. short mode;
  244. RgnHandle maskRgn;
  245. {
  246. #ifdef applec
  247. #pragma unused (srcRect, dstRect, mode, maskRgn)
  248. #endif
  249.     PixMapPtr aPixMap;
  250.     short tempRB;
  251.  
  252.     /* Get the PixMap that we are about to draw.  SrcBits might be a BitMap, or
  253.         one of two different kinds of PixMap pointers.  */
  254.     tempRB = (*bitPtr).rowBytes;            /* local copy of rowBytes */
  255.     if (tempRB < 0) {                        /* high bit set? */
  256.         if ((tempRB<<1) < 0)                /* next to high bit set? */
  257.             aPixMap = (** ( (PixMapHandle *)bitPtr ));    /* ptr to PixMap handle */
  258.         else
  259.             aPixMap = (PixMapPtr) bitPtr;        /* pointer to a PixMap */
  260.         if ((*aPixMap).pixelSize > maxPixDepth)    /* deepest pixmap so far? */
  261.             maxPixDepth = (*aPixMap).pixelSize;
  262.         if ((*aPixMap).pixelType==16) {
  263.             foundDirect = true;
  264.             return;                                /* direct pixmap?  eek! */
  265.         }
  266.         AddColorTable((*aPixMap).pmTable);        /* it has its own color table. */
  267.     }
  268.     else {
  269.         /* It's just a BitMap; it will use the background and foreground colors. */
  270.         AddRGBBackColor();
  271.         AddRGBForeColor();
  272.     }
  273. }
  274.  
  275. RGBColor whiteRGB = { 0xFFFF,0xFFFF,0xFFFF };
  276. RGBColor blackRGB = { 0,0,0 };
  277.  
  278. CTabHandle CollectColors(fromPicture, depthPtr, directFlagPtr)
  279. PicHandle fromPicture;
  280. short *depthPtr;
  281. short *directFlagPtr;
  282. {
  283.     CTabHandle colors;
  284.     CQDProcs bottlenecks;
  285.  
  286.     /* Set the bottlenecks.  These bottlenecks will figure out what colors are in
  287.         a picture, but won't draw anything.
  288.     Note: the bottlenecks are installed in thePort, which must be a color port.
  289.     */
  290.     SetStdCProcs(&bottlenecks);
  291.     bottlenecks.textProc = (Ptr) ColorTextProc;
  292.     bottlenecks.lineProc = (Ptr) ColorLineProc;
  293.     bottlenecks.rectProc = (Ptr) ColorRectProc;
  294.     bottlenecks.rRectProc = (Ptr) ColorRRectProc;
  295.     bottlenecks.ovalProc = (Ptr) ColorOvalProc;
  296.     bottlenecks.arcProc = (Ptr) ColorArcProc;
  297.     bottlenecks.polyProc = (Ptr) ColorPolyProc;
  298.     bottlenecks.rgnProc = (Ptr) ColorRgnProc;
  299.     bottlenecks.bitsProc = (Ptr) ColorBitsProc;
  300.  
  301.     /* Create a color table containing black and white. */
  302.     foundDirect = false;    /* haven't found a direct pixmap yet */
  303.     maxPixDepth = 1;        /* assume we will find a bitmap */
  304.     colors = (CTabHandle) NewHandle( sizeof(ColorTable) + sizeof(ColorSpec) );
  305.     if (colors) {
  306.         (**colors).ctSize = 1; /* 2 entries */
  307. #ifdef applec
  308.         (**colors).ctFlags = 0x8000;
  309. #else
  310.         (**colors).transIndex = 0x8000;
  311. #endif
  312.         (**colors).ctSeed = GetCTSeed();
  313.         (**colors).ctTable[0].rgb = whiteRGB; /*first entry is white*/
  314.         (**colors).ctTable[1].rgb = blackRGB; /*second entry is black*/
  315.         /* Now play back the picture to get the colors.  The dstRect doesn't
  316.             matter since our bottlenecks will never actually draw. We use global
  317.             variables (gColorError and gColorTable) to communicate with the
  318.             bottlenecks. */
  319. #ifdef applec
  320.         (*(qd.thePort)).grafProcs = (QDProcs *) &bottlenecks;
  321. #else
  322.         (*thePort).grafProcs = (QDProcs *) &bottlenecks;
  323. #endif
  324.         gColorError = noErr;
  325.         gColorTable = colors;
  326.         DrawPicture(fromPicture, &((**fromPicture).picFrame));
  327. #ifdef applec
  328.         (*(qd.thePort)).grafProcs = 0L;
  329. #else
  330.         (*thePort).grafProcs = 0L;
  331. #endif
  332.         *depthPtr = maxPixDepth;
  333.         *directFlagPtr = foundDirect;
  334.  
  335.         /* Fail if error occurred while within the color bottlenecks. */
  336.         if (gColorError != noErr) {
  337.             DisposHandle((Handle)colors);
  338.             colors = 0L;
  339.         }
  340.     }
  341.     return colors;
  342. }
  343.